package com.szjz.elasticsearch.eshelper.scheduled;

import com.szjz.elasticsearch.eshelper.animation.ESTable;
import com.szjz.elasticsearch.eshelper.property.ESRestClientProperties;
import com.szjz.elasticsearch.eshelper.service.ESService;
import com.szjz.elasticsearch.eshelper.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author 史博
 * @desc 索引库调度任务
 * @date 2020/11/4 1:33 下午 周三
 */
@Slf4j
@Component
public class IndexScheduled {

    @Autowired
    private ESService esService;
    @Autowired
    private ESRestClientProperties esRestClientProperties;
    private String CRON_SEC = "* * * * * ? ";
    private String CRON_YEAR = "0 0 0 01 01 ? ";

    /**
     * 每天定时创建第二天的索引库
     */
    @Scheduled(cron = "${spring.elasticsearch.rest.esCreateIndexCron:0 0 0 01 01 ? }")
    public void createIndexScheduled() {
        createIndex();
    }

    /**
     * 每6个小时创建一次
     */
    @Scheduled(cron = "0 0 0/6 * * ?")
    public void createIndex() {
        // 创建未来4天的索引库
        List<String> esEntityPaths = esRestClientProperties.getEsCreateIndexEntityPaths();
        String createIndexCron = esRestClientProperties.getEsCreateIndexCron();
        if (createIndexCron != null && !CollectionUtils.isEmpty(esEntityPaths)) {
            for (int i = 0; i < 4; i++) {
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.DAY_OF_MONTH, 1 + i);
                for (String esEntityPath : esEntityPaths) {
                    Class<?> aClass = null;
                    try {
                        aClass = Class.forName(esEntityPath);
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                        log.error("【定时创建索引库-按天分库】创建失败！es实体类路径错误：{}", esEntityPath);
                    }
                    // @ESTable注解的实体类
                    assert aClass != null;
                    if (aClass.isAnnotationPresent(ESTable.class)) {
                        ESTable esTable = aClass.getAnnotation(ESTable.class);
                        String indexName = esTable.indexName() + "-" + DateUtils.format(calendar.getTime(), DateUtils.YYYY_MM_DD);
                        esService.createIndex(indexName, aClass);
                        log.info("【定时创建索引库-按天分库】indexName: {}  cron: {}", indexName, createIndexCron);
                    }
                }
            }
        } else {
            log.info("【定时创建索引库-按天分库】yml文件配置条件不满足无法创建 cron: {} {} （如果服务中没有按天分库的业务可忽略提示）", createIndexCron, DateUtils.format(new Date(), DateUtils.PATTERN_YYMMDDHHMMSS));
        }
    }

    /**
     * 每天定时执行删除n天以前的索引库
     */
    @Scheduled(cron = "${spring.elasticsearch.rest.esDeleteIndexCron:0 0 0 01 01 ? }")
    public void deleteIndexScheduled() {
        deleteIndex();
    }

    /**
     * 每12个小时删除一次
     */
    @Scheduled(cron = "0 0 0/12 * * ?")
    public void deleteIndex() {
        String deleteIndexCron = esRestClientProperties.getEsDeleteIndexCron();
        Integer beforeDay = esRestClientProperties.getSearchBeforeDay();
        List<String> deleteIndexEntityPaths = esRestClientProperties.getEsDeleteIndexEntityPaths();
        if (deleteIndexCron != null && beforeDay != null && !CollectionUtils.isEmpty(deleteIndexEntityPaths)) {
            for (int i = 0; i < 3; i++) {
                Integer searchBeforeDay = esRestClientProperties.getSearchBeforeDay();
                if (searchBeforeDay != null && searchBeforeDay <= 0) {
                    throw new IllegalArgumentException("【定时删除索引库】searchBeforeDay 值必须 > 0");
                }
                List<String> esEntityPaths = esRestClientProperties.getEsDeleteIndexEntityPaths();
                Calendar calendar = Calendar.getInstance();
                if (searchBeforeDay != null) {
                    calendar.add(Calendar.DAY_OF_MONTH, -searchBeforeDay + (-i));
                    for (String esEntityPath : esEntityPaths) {
                        Class<?> aClass = null;
                        try {
                            aClass = Class.forName(esEntityPath);
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                            log.error("【定时删除索引库-按天分库】删除失败！es实体类路径错误：{}", esEntityPath);
                        }
                        // @ESTable注解的实体类
                        assert aClass != null;
                        if (aClass.isAnnotationPresent(ESTable.class)) {
                            ESTable esTable = aClass.getAnnotation(ESTable.class);
                            String indexName = esTable.indexName() + "-" + DateUtils.format(calendar.getTime(), DateUtils.YYYY_MM_DD);
                            esService.deleteIndex(indexName);
                            log.info("【定时删除索引库-按天分库】indexName: {}  cron: {}", indexName, deleteIndexCron);
                        }
                    }
                }
            }
        } else {
            log.info("【定时删除索引库-按天分库】yml文件配置条件不满足无法删除 cron: {} {} （如果服务中没有按天分库的业务可忽略提示）", deleteIndexCron, DateUtils.format(new Date(), DateUtils.PATTERN_YYMMDDHHMMSS));
        }
    }



	/**
	 * 按月分库--防止意外发生，每月个的25到31号每天创建一次索引库
	 */
	@Scheduled(cron = "0 21 21 25-31 * ?")
	public void createIndexAcMonth() {
		List<String> esEntityPaths = esRestClientProperties.getMonth().getCreateIndexEntityPaths();
		if (!CollectionUtils.isEmpty(esEntityPaths)) {
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.MONTH, 1 );
			for (String esEntityPath : esEntityPaths) {
				Class<?> aClass = null;
				try {
					aClass = Class.forName(esEntityPath);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
					log.error("【定时创建索引库-按月分库】创建失败！es实体类路径错误：{}", esEntityPath);
				}
				// @ESTable注解的实体类
				assert aClass != null;
				if (aClass.isAnnotationPresent(ESTable.class)) {
					ESTable esTable = aClass.getAnnotation(ESTable.class);
					String indexName = esTable.indexName() + "-" + DateUtils.format(calendar.getTime(), DateUtils.YYYY_MM);
					esService.createIndex(indexName, aClass);
					log.info("【定时创建索引库-按月分库】indexName: {} ", indexName);
				}
			}
		} else {
			log.info("【定时创建索引库-按月分库】yml文件配置条件不满足无法创建 {} （如果服务中没有按月分库的业务可忽略提示）", DateUtils.format(new Date(), DateUtils.PATTERN_YYMMDDHHMMSS));
		}
	}


}
